/*
 * udp-p2sp.h
 *
 *  Created on: 2009-11-2
 *      Author: root
 */

#ifndef UDPP2SP_H_
#define UDPP2SP_H_

#include "udp.h"
#include "ip.h"
#include "map"
#define MAX_CHKMAP 65536
#define BUFSIZE 1024*1024

//p2sp packet types
typedef enum p2sp_pkt_type {
  PEER_INFO = 1,
  PEER_DATA = 2,
  SRVR_REQUEST = 3,
  SRVR_DATA = 4,
  CHUNKMAP_REQ = 5,
  CHUNKMAP_CONF = 6,
  IS_RECVING = 7,
  PEER_JOIN = 8,
} p2sp_pkt_t;

/*typedef struct {
p2sp_pkt_t type_;         //packet type?
uint16_t chunk_id_;    //chunk id
int nbytes_;   //bytes for p2sp pkt
nsaddr_t src_id_;
nsaddr_t dst_id_;
int seqno_;
uint32_t req_bmp_[MAXBMPS];  //request bitmap put into appdata
}p2sp_req_t;*/

typedef struct {
	p2sp_pkt_t type_;         //packet type?
	uint16_t chunk_id_;    //chunk id
	int nbytes_;   //bytes for p2sp pkt
	int chkmap_id_;
	nsaddr_t src_id_;
	nsaddr_t dst_id_;
	uint16_t peer_id_;
	uint16_t group_size_;
	int seqno_;
} p2sp_data_t;

//p2sp Application Header Structure
struct hdr_p2sp{
  p2sp_pkt_t type;         //packet type?
  uint16_t chunk_id;    //chunk id
//  uint64_t req_bmp[MAXBMPS];  //request bitmap put into appdata
  int nbytes;   //bytes for p2sp pkt
  nsaddr_t src_addr;
  nsaddr_t dst_addr;
  nsaddr_t src_port;
  nsaddr_t dst_port;

  int seq;     // sequence number
  int data_off_;


  //Packet header access functions
  static int offset_;
  inline static int& offset() {return offset_;}
  inline static hdr_p2sp* access(const Packet* p) {
    return (hdr_p2sp*) p->access(offset_);
  }
};


// Used for Re-assemble segmented (by UDP) P2SP packet
typedef struct asm_p2sp {
        int seq;     // p2sp sequence number
        nsaddr_t src;//src addr of the packet
        int rbytes;  // currently received bytes
        int tbytes;  // total bytes to receive for p2sp packet
        unsigned char buf[BUFSIZE];
} asm_p2sp_t;

typedef std::map<nsaddr_t, asm_p2sp_t> asm_t;

// Udp2spAgent Class definition
class Udp2spAgent : public UdpAgent {
public:
        Udp2spAgent();
        Udp2spAgent(packet_t);
        virtual int supportp2sp() { return 1; }
        virtual void enablep2sp() { support_p2sp_ = 1; }
        virtual void sendmsg(int nbytes, const char *flags = 0);
        virtual void sendmsg(int nbytes, AppData* data, const char *flags = 0);
        virtual void sendto(int nbytes, AppData* data, const char *flags, nsaddr_t dst);
        void recv(Packet*, Handler*);

protected:
        int support_p2sp_; // set to 1 if above is p2sp App
private:
        asm_t asm_info; // packet re-assembly information
        int seq_;
};

#endif /* UDPP2SP_H_ */
